package gensql

import (
	"fmt"
	"navi-mumbai/common/xerr"
	"strconv"
	"time"
)

type GenSql struct {
	sql      string
	whereSql string
	values   []interface{}
}

func NewGenSql() *GenSql {
	return &GenSql{}
}

func (g *GenSql) InitSql(query string, args ...interface{}) {
	g.sql = query
	g.values = make([]interface{}, 0)
	g.whereSql = ""
	for _, arg := range args {
		g.values = append(g.values, arg)
	}
}

func (g *GenSql) Where(field string, args ...interface{}) *GenSql {
	if len(g.whereSql) <= 0 {
		g.whereSql = " where " + field
	} else {
		g.whereSql += " and " + field
	}
	for _, arg := range args {
		g.values = append(g.values, g._interface2String(arg))
	}
	return g
}

func (g *GenSql) Set(field string, args ...interface{}) *GenSql {
	if len(g.whereSql) <= 0 {
		g.whereSql = " set " + field + " = "
	} else {
		g.whereSql += " , " + field + " = "
	}
	for _, arg := range args {
		g.values = append(g.values, g._interface2String(arg))
	}
	return g
}

func (g *GenSql) _interface2String(inter interface{}) string {
	totalStr := ""
	switch inter.(type) {
	case *time.Time:
		totalStr += inter.(*time.Time).String()
	case int64:
		totalStr += strconv.FormatInt(inter.(int64), 10)
	case int:
		totalStr += strconv.FormatInt(int64(inter.(int)), 10)
	case float64:
		totalStr += strconv.FormatFloat(inter.(float64), 'f', 2, 64)
	case string:
		totalStr += inter.(string)
	case []int64:
		for j, v2 := range inter.([]int64) {
			totalStr += strconv.FormatInt(v2, 10)
			if j == len(inter.([]int64))-1 {
				break
			}
			totalStr += ","
		}
	case []string:
		for j, v2 := range inter.([]string) {
			totalStr += v2
			if j == len(inter.([]string))-1 {
				break
			}
			totalStr += ","
		}
	case []int:
		for j, v2 := range inter.([]int) {
			totalStr += strconv.FormatInt(int64(v2), 10)
			if j == len(inter.([]int))-1 {
				break
			}
			totalStr += ","
		}
	case []float64:
		for j, v2 := range inter.([]float64) {
			totalStr += strconv.FormatFloat(v2, 'f', 2, 64)
			if j == len(inter.([]float64))-1 {
				break
			}
			totalStr += ","
		}
	default:
		fmt.Printf("miss deal type %#v", inter)
	}

	return totalStr
}

func (g *GenSql) OrderBy(dsp string) *GenSql {
	g.whereSql += " order by " + dsp
	return g
}

func (g *GenSql) Limit(pageSize uint64) *GenSql {
	g.whereSql += " limit " + strconv.FormatUint(pageSize, 10)
	return g
}

func (g *GenSql) Offset(offset uint64) *GenSql {
	g.whereSql += " offset " + strconv.FormatUint(offset, 10)
	return g
}

func (g *GenSql) ToSql() (string, []interface{}, error) {
	if len(g.sql) <= 0 {
		return "", nil, xerr.NewErrCode(xerr.DbError)
	}
	g.sql += g.whereSql
	return g.sql, g.values, nil
}
